package middleware

import (
	"net/http"
	"strings"

	"gitee.com/zhenyangze/gin-framework/internal/app/bases"
	"github.com/gin-gonic/gin"
)

// RequestValidator provides common validation middleware
type RequestValidator struct{}

// ValidateJSONContentType ensures request has proper JSON content type
func (rv *RequestValidator) ValidateJSONContentType() gin.HandlerFunc {
	return func(c *gin.Context) {
		if c.Request.Method == "POST" || c.Request.Method == "PUT" || c.Request.Method == "PATCH" {
			contentType := c.GetHeader("Content-Type")
			if !strings.Contains(contentType, "application/json") {
				c.JSON(http.StatusBadRequest, bases.JsonError("Content-Type must be application/json", nil))
				c.Abort()
				return
			}
		}
		c.Next()
	}
}

// ValidateContentLength limits request body size
func (rv *RequestValidator) ValidateContentLength(maxSize int64) gin.HandlerFunc {
	return func(c *gin.Context) {
		if c.Request.ContentLength > maxSize {
			c.JSON(http.StatusRequestEntityTooLarge, bases.JsonError("Request body too large", nil))
			c.Abort()
			return
		}
		c.Next()
	}
}

// SecurityHeaders adds common security headers
func SecurityHeaders() gin.HandlerFunc {
	return func(c *gin.Context) {
		c.Header("X-Content-Type-Options", "nosniff")
		c.Header("X-Frame-Options", "DENY")
		c.Header("X-XSS-Protection", "1; mode=block")
		c.Header("Strict-Transport-Security", "max-age=31536000; includeSubDomains")
		c.Header("Content-Security-Policy", "default-src 'self'")
		c.Next()
	}
}

// InputSanitizer provides basic input sanitization
func InputSanitizer() gin.HandlerFunc {
	return func(c *gin.Context) {
		// Sanitize common XSS patterns in URL parameters
		for key, values := range c.Request.URL.Query() {
			for i, value := range values {
				// Basic XSS prevention
				sanitized := strings.ReplaceAll(value, "<script", "&lt;script")
				sanitized = strings.ReplaceAll(sanitized, "</script>", "&lt;/script&gt;")
				sanitized = strings.ReplaceAll(sanitized, "javascript:", "")
				sanitized = strings.ReplaceAll(sanitized, "vbscript:", "")
				values[i] = sanitized
			}
			c.Request.URL.Query()[key] = values
		}
		c.Next()
	}
}